#include "mpi.h"
#include <cstdio>
#include <cstdlib>
#include <cmath>
// #define DEBUG

double f (double x) { return x * x; }

double Trap (
    double left_endpt,   // in
    double right_endpt,  // in
    int trap_count,      // in 
    double base_len      // in
) {
    double estimate, x;
    estimate = (f(left_endpt) + f(right_endpt)) / 2.0;
    for (int i = 1; i < trap_count; ++i)
        x = left_endpt + i * base_len,
        estimate += f(x);
    estimate = estimate * base_len;
    return estimate;
}

const int MAX_TEST = 1024 * 1024 * 3;
float sendbuf[MAX_TEST];
float recvbuf[MAX_TEST];
int main() {

    int my_rank, comm_sz;

    MPI_Init(NULL, NULL);

    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
    
    for (int i = 0; i < MAX_TEST; ++i) sendbuf[i] = 1.0;

    MPI_Allreduce((void*)sendbuf , (void*)recvbuf , MAX_TEST, MPI_FLOAT, MPI_SUM, MPI_COMM_WORLD);

    {
        int tmp = 0;
        for (int i = 0; i < MAX_TEST; ++i)
            if (abs(recvbuf[i] - (comm_sz)) > 1e-6) {
                printf("Error with proc %d\n", my_rank);
                tmp = 1;
                break;
            }

        if (tmp == 0) {
            printf("Accept on %d!!!\n", my_rank);
        }
    }

#ifdef DEBUG
    if (my_rank == 0) {
        printf("ans = [");
        for (int i = 0; i < MAX_TEST; ++i)
            printf("%.2f, ", recvbuf[i]);
        printf("]\n");
    }
#endif // DEBUG

    MPI_Finalize(); 

    return 0;
}